// src/utils/request.ts
import axios, { AxiosError } from "axios";
import type { AxiosResponse } from "axios";
import type { Response } from "@/service/api/types/request";

import { getStore } from "@/store";
import { getToken } from "../api/modules/auth";

// 用于和后端响应的axios实例
export const instance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL,
    timeout: 10000,
});

// 用于进行其他网络请求的axios实例
const otherInstance = axios.create({
    timeout: 10000,
});

// 请求拦截器
instance.interceptors.request.use(
    (config) => {
        // 控制是否默认显示loading
        if (!Object.keys(config).includes("loading")) {
            window.NLoading.show({ text: "请求中..." });
        }

        const token = getToken();
        if (token && getStore("user")!.isAuthenticated) {
            config.headers.Authorization = `${token}`; // 将 token 添加到请求头中
        }

        return config;
    },
    (error: AxiosError) => {
        return Promise.reject(error);
    }
);

// 响应拦截器
instance.interceptors.response.use(
    (response: AxiosResponse<Response<any>>) => {
        // 直接返回整个响应对象
        window.NLoading.hide();
        return response;
    },
    (error: AxiosError) => {
        // 统一错误处理，返回 statusText
        window.NLoading.hide();
        console.log(error);
        return Promise.reject(
            new Error(error.response?.statusText || "Network Error")
        );
    }
);

/**
 * 封装的 request 请求方法
 * @param url 请求地址
 * @param data 请求数据
 * @param method 请求方法 -> get | post | delete | put
 * @returns 响应数据
 */
export const request = async <T = any>(
    url: string,
    method: "get" | "post" | "delete" | "put",
    data: any,
    config?: {
        headers?: { [key: string]: string };
        loading?: boolean;
        baseUrl?: boolean;
    }
): Promise<T> => {
    try {
        let response: AxiosResponse<Response<T>>;

        const axiosConfig = { ...config, headers: { ...config?.headers } };

        if (method === "get" || method === "delete") {
            url = data ? `${url}${new URLSearchParams(data).toString()}` : url;

            response = await instance[method]<Response<T>>(url, axiosConfig);
        } else {
            const requestData =
                typeof data === "string" ? JSON.parse(data) : data;

            response = await instance[method]<Response<T>>(
                url,
                requestData,
                axiosConfig
            );
        }
        if (response.data.code !== 1) {
            throw new Error(response.data.message || "Request failed");
        }
        return response.data.data; // 直接返回 data 部分
    } catch (error) {
        throw new Error((error as Error).message || "Request failed");
    }
};

/**
 * 其他网络请求方法
 * @param url
 * @param method
 * @param data
 * @returns
 */
export const otherRequest = async (
    url: string,
    method: "get" | "post" | "delete" | "put",
    data: any
) => {
    try {
        const response = await otherInstance[method](url, data);
        return response;
    } catch (error) {
        throw new Error((error as Error).message || "Request failed");
    }
};
